﻿//
//  Monkey Manager
//  Copyright (C) 2012 Victor Tereschenko
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//     
// ========================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ManagerDB;

namespace AddManager
{
    /// <summary>
    /// Arguments for duplicate file found event.
    /// </summary>
    public class DuplicateFoundEventArgs : EventArgs
    {
        public DuplicateFoundEventArgs(string path)
        {
            Path = path;
        }

        public string Path { get; private set; }
    }

    /// <summary>
    /// Arguments for missing file found event.
    /// </summary>
    public class MissingFoundEventArgs : EventArgs
    {
        public MissingFoundEventArgs(string path, StoredFile file)
        {
            Path = path;
            File = file;
        }

        public string Path { get; private set; }
        public StoredFile File { get; private set; }
    }

    /// <summary>
    /// When there is no work for a hasher finds old "unhashed" item in DB and calcs hash for it.
    /// </summary>
    class AutoHasher
    {
        IDatabase mDatabase;
        HashCalculator mHasher;
        Filter mFilter;

        public AutoHasher(IDatabase database, HashCalculator hasher)
        {
            mDatabase = database;
            mFilter = new Filter();
            mFilter.FileStatus = FileStatus.Present;
            mFilter.TTH = "";
            mFilter.Limit = 1;
            mHasher = hasher;
            mHasher.FileHashed += new EventHandler<FileHashedEventArgs>(onFileHashed);

            if (mHasher.IsEmptyQueue)
                addFile();
        }

        public EventHandler<DuplicateFoundEventArgs> DuplicateFound;
        public EventHandler<MissingFoundEventArgs> MissingFound;

        void onFileHashed(object sender, FileHashedEventArgs e)
        {
            if (mFiles.Length > 0)
            {
                var path = mDatabase.GetPath(mFiles[0]);
                if (path == e.FileName)
                {
                    var info = new System.IO.FileInfo(path);
                    var duplicate = mDatabase.Find(e.TTH, info.Length);
                    if (duplicate != null)
                        DuplicateFound(this, new DuplicateFoundEventArgs(path));
                    mFiles[0].File.ID.TTH = e.TTH;
                    mDatabase.Update(mFiles[0]);
                }
            }
            if (!mHasher.IsEmptyQueue)
                return;

            addFile();
        }

        StoredFile[] mFiles;
        private void addFile()
        {
            while (true)
            {
                mFiles = mDatabase.Find(mFilter);
                if (mFiles.Length < 1)
                    return;
                var path = mDatabase.GetPath(mFiles[0]);
                if (path == null)
                    return;
                if (System.IO.File.Exists(path))
                {
                    mHasher.Add(path);
                    break;
                }
                else
                {
                    if (MissingFound != null)
                        MissingFound(this, new MissingFoundEventArgs(path, mFiles[0]));
                    mFilter.Offset += 1;
                }
            }
        }
    }
}
